using System;
using System.IO;
using System.Web.Hosting;
using Common.Infrastructure;
using Core.Infrastructure.StructureMap;
using GemBox.Spreadsheet;
using NServiceBus;
using NServiceBus.Features;
using Sanelib.Initialization;
using StructureMap;
using WebApp.Initialization.Automapper;

namespace WebApp.Initialization
{
    public class ClientEndPoint
    {
        private static bool _initialized;
        private static readonly object Lock = new object();

        private ClientEndPoint() { }

        public static void Initialize()
        {
            if (_initialized) return;
            lock (Lock)
            {
                if (_initialized) return;
                CheckConfigurations();
                ConfigureStructureMap();
                ConfigureBus();
                _initialized = true;
            }
        }      

        private static void ConfigureStructureMap()
        {
            ObjectFactory.Initialize(x => x.Scan(scan =>
            {
                scan.TheCallingAssembly();
                scan.AssemblyContainingType<SanelibRegistry>();
                scan.AssemblyContainingType<CommonRegistry>();
                scan.AssemblyContainingType<CoreRegistry>();
                scan.AssemblyContainingType<UiRegistry>();
                scan.WithDefaultConventions();
                scan.LookForRegistries();
            }));

            AutoMapperConfiguration.Configure(ObjectFactory.GetInstance);

            SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
        }

        private static void ConfigureBus()
        {
            Configure.Serialization.Json();
            Configure.Transactions.Enable();
            Configure.Features.Enable<Sagas>();

            Configure.With()
                .DefineEndpointName("SanelibWeb")
                .StructureMapBuilder(ObjectFactory.Container)
                .DefiningCommandsAs(t => t.Namespace != null && t.Namespace.StartsWith("NSBus.Dto.Commands"))
                .DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("NSBus.Dto.Events"))
                .DefiningMessagesAs(t => t.Namespace != null && t.Namespace.StartsWith("NSBus.Dto.Messages"))
                .RavenPersistence()
                .RavenSubscriptionStorage()
                .RavenSagaPersister()
                .UseRavenTimeoutPersister()
                .UseRavenGatewayPersister()
                .PurgeOnStartup(false)
                .UnicastBus().ImpersonateSender(false).CreateBus()
                .Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
        }

        private static void CheckConfigurations()
        {
            string srcPath;
            var path = HostingEnvironment.MapPath("~");

            if (string.IsNullOrEmpty(path))
            {
                path = AppDomain.CurrentDomain.BaseDirectory + "\\";

                srcPath = path + "..\\Deployment\\Configs";

                if (!Directory.Exists(srcPath))
                {
                    srcPath = path + "..\\..\\..\\Deployment\\Configs";
                    if (!Directory.Exists(srcPath))
                    {
                        throw new Exception("Src config directory not exist at " + srcPath);
                    }
                }
            }
            else
            {
                srcPath = path + "..\\Deployment\\Configs";
                if (!Directory.Exists(srcPath))
                {
                    throw new Exception("Src config directory not exist at " + srcPath);
                }
            }

            var destPath = path + "Configs\\";

            Console.WriteLine("Source config path: " + srcPath);
            Console.WriteLine("Dest config path: " + destPath);

            System.Threading.Thread.Sleep(3000);

            if (!Directory.Exists(destPath)) Directory.CreateDirectory(destPath);

            var configDirectory = new DirectoryInfo(srcPath);

            var configs = configDirectory.GetFiles("*.xml");
            foreach (var fileInfo in configs)
            {
                var destFileName = destPath + fileInfo.Name;
                fileInfo.CopyTo(destFileName, true);
            }
        }

        //private void TestWebConfig()
        //{
        //    ApplyAppConfig("StartupTime", DateTime.Now.ToString(CultureInfo.InvariantCulture));

        //    var generalConfig = ConfigProvider.GetGeneralConfig();
        //    if (!string.IsNullOrEmpty(generalConfig.RunMode)) return;

        //    generalConfig = new GeneralConfig
        //    {
        //        RunMode = "Debug",
        //        DoNotLogInfo = false,
        //        LogOutputTo = "File",
        //        StoreConfigInDatabase = false,
        //        ApplicationBaseUrl = "http://localhost:9095",
        //        ApplicationHealthUrl = "http://localhost:9095/MemberRegistration/record"
        //    };
        //    ConfigProvider.SetGeneralConfig(generalConfig, true);
        //}

        //private void ApplyAppConfig(string key, string value)
        //{
        //    var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
        //    var isAvailable = config.AppSettings.Settings.AllKeys.Any(x => x == key);
        //    if (isAvailable)
        //    {
        //        config.AppSettings.Settings[key].Value = value;
        //    }
        //    else
        //    {
        //        config.AppSettings.Settings.Add(key, value);
        //    }
        //    config.Save();
        //}
    }
}